package com.kyivmohyla.kma2.client.presenter.refbook;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.Widget;
import com.kyivmohyla.kma2.client.UserService;
import com.kyivmohyla.kma2.client.gin.Injector;
import com.kyivmohyla.kma2.client.presenter.Presenter;
import com.kyivmohyla.kma2.client.utils.Dialog;
import com.kyivmohyla.kma2.shared.model.UIService;
import com.smartgwt.client.types.AnimationAcceleration;
import com.smartgwt.client.types.SelectionAppearance;
import com.smartgwt.client.types.TreeModelType;
import com.smartgwt.client.widgets.events.DrawEvent;
import com.smartgwt.client.widgets.events.DrawHandler;
import com.smartgwt.client.widgets.grid.ListGridRecord;
import com.smartgwt.client.widgets.tree.Tree;
import com.smartgwt.client.widgets.tree.TreeGrid;
import com.smartgwt.client.widgets.tree.TreeGridField;
import com.smartgwt.client.widgets.tree.TreeNode;

import java.util.ArrayList;
import java.util.List;

public class ServiceReferenceBookPresenter implements Presenter {
    private final Display display;
    private final Injector injector = Injector.INSTANCE;
    private List<UIService> servicesOnOrder;

    public ServiceReferenceBookPresenter() {
        final DialogBox waiter = Dialog.getInstance().createWaiter();
        this.display = injector.getServiceReferenceBookView();
        UserService.App.getInstance().getServiceAllService(new AsyncCallback<List<UIService>>() {
            @Override
            public void onFailure(Throwable throwable) {
                Dialog.getInstance().createDialogBoxWithMessage("Error", throwable.getMessage());
            }

            @Override
            public void onSuccess(List<UIService> result) {
                TreeGridField ServiceIdField = new TreeGridField("Id");
                TreeGridField NameField = new TreeGridField("Name");
                TreeGridField DescriptionField = new TreeGridField("Description");
                display.getTreeGrid().setFields(ServiceIdField, NameField, DescriptionField);
                final Tree tree = new Tree();
                tree.setModelType(TreeModelType.PARENT);
                tree.setNameProperty("Name");
                tree.setIdField("Id");
                tree.setParentIdField("ReportsTo");
                tree.setShowRoot(false);
                TreeNode[] treeNodes = new TreeNode[result.size()];
                for (int i = 0; i < treeNodes.length; ++i) {
                    int parentId;
                    if (result.get(i).getIsParent() == 1) {
                        parentId = 0;
                    } else {
                        parentId = result.get(i).getParentId();
                    }
                    treeNodes[i] = new TreeGridNode(result.get(i).getServiceId(),
                            parentId,
                            result.get(i).getName(),
                            result.get(i).getDescription());
                }
                tree.setData(treeNodes);
                display.getTreeGrid().addDrawHandler(new DrawHandler() {
                    public void onDraw(DrawEvent event) {
                        tree.openAll();
                    }
                });
                display.getTreeGrid().setSelectionAppearance(SelectionAppearance.CHECKBOX);
                display.getTreeGrid().setAnimateFolderEffect(AnimationAcceleration.SMOOTH_START_END);
                display.getTreeGrid().setData(tree);
                display.getTreeGrid().redraw();
                waiter.hide();
            }
        });
        bind();
    }

    public ServiceReferenceBookPresenter(final List<UIService> services) {
        final DialogBox waiter = Dialog.getInstance().createWaiter();
        this.display = injector.getServiceReferenceBookView();
        UserService.App.getInstance().getServiceAllService(new AsyncCallback<List<UIService>>() {
            @Override
            public void onFailure(Throwable throwable) {
                Dialog.getInstance().createDialogBoxWithMessage("Error", throwable.getMessage());
            }

            @Override
            public void onSuccess(List<UIService> result) {
                TreeGridField ServiceIdField = new TreeGridField("Id");
                TreeGridField NameField = new TreeGridField("Name");
                TreeGridField DescriptionField = new TreeGridField("Description");
                display.getTreeGrid().setFields(ServiceIdField, NameField, DescriptionField);
                final Tree tree = new Tree();
                tree.setModelType(TreeModelType.PARENT);
                tree.setNameProperty("Name");
                tree.setIdField("Id");
                tree.setParentIdField("ReportsTo");
                tree.setShowRoot(false);
                TreeNode[] treeNodes = new TreeNode[result.size()];
                for (int i = 0; i < treeNodes.length; ++i) {
                    int parentId;
                    if (result.get(i).getIsParent() == 1) {
                        parentId = 0;
                    } else {
                        parentId = result.get(i).getParentId();
                    }
                    treeNodes[i] = new TreeGridNode(result.get(i).getServiceId(),
                            parentId,
                            result.get(i).getName(),
                            result.get(i).getDescription());
                }
                tree.setData(treeNodes);
                display.getTreeGrid().addDrawHandler(new DrawHandler() {
                    public void onDraw(DrawEvent event) {
                        tree.openAll();
                    }
                });
                display.getTreeGrid().setSelectionAppearance(SelectionAppearance.CHECKBOX);
                display.getTreeGrid().setAnimateFolderEffect(AnimationAcceleration.SMOOTH_START_END);
                display.getTreeGrid().setData(tree);
                display.getTreeGrid().redraw();
                servicesOnOrder = result;
                display.getTreeGrid().getTree().openAll();
                for (UIService service : services) {
                    display.getTreeGrid().getTree().openAll();
                    for (int i = 0; i < display.getTreeGrid().getRecords().length; i++) {
                        if (display.getTreeGrid().getRecord(i).getAttribute("Id").equals(String.valueOf(service.getServiceId()))) {
                            display.getTreeGrid().selectRecord(i, true);
                        }
                    }
                }
                waiter.hide();
            }
        });
        bind();
    }

    private void bind() {
        this.display.getAddButton().addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent clickEvent) {
                servicesOnOrder = new ArrayList<UIService>();
                ListGridRecord[] records = display.getTreeGrid().getSelectedRecords();
                for (ListGridRecord record : records) {
                    UIService service = new UIService();
                    if (record.getAttribute("ReportsTo") == null) {
                        service.setParentId(0);
                        service.setIsParent(1);
                    } else {
                        service.setParentId(record.getAttributeAsInt("ReportsTo"));
                        service.setIsParent(0);
                    }
                    service.setServiceId(record.getAttributeAsInt("Id"));
                    service.setDescription(record.getAttribute("Description"));
                    service.setName(record.getAttribute("Name"));
                    if (service.getIsParent() == 0) {
                        servicesOnOrder.add(service);
                    }
                }
            }
        });
    }

    @Override
    public void go(HasWidgets container) {
        container.clear();
        container.add(display.asWidget());
    }

    public List<UIService> getServicesOnOrder() {
        return this.servicesOnOrder;
    }

    public Display getDisplay() {
        return this.display;
    }

    public interface Display {
        TreeGrid getTreeGrid();

        HasClickHandlers getAddButton();

        HasClickHandlers getCancelButton();

        Widget asWidget();
    }
}
